#include <stdio.h>
#include <stdint.h>

#define MBR_SIZE 512                     ///< 主引导记录（MBR）的大小，单位为字节
#define PARTITION_TABLE_START 446        ///< 分区表在MBR中的起始偏移量
#define PARTITION_ENTRY_SIZE 16          ///< 每个分区条目的大小，单位为字节
#define NUM_PARTITIONS 4                 ///< MBR中包含的分区数量

/**
 * @struct PartitionEntry
 * @brief 表示分区表中的一个分区条目
 * 
 * 该结构体用于存储分区表中关于一个分区的详细信息，包括其状态、起始和结束位置、类型等。
 */
typedef struct {
    uint8_t status;          ///< 分区状态（活动标志），0x80表示活动分区
    uint8_t start_head;      ///< 起始头
    uint8_t start_sector;    ///< 起始扇区（低6位有效）
    uint8_t start_cylinder;  ///< 起始柱面
    uint8_t partition_type;  ///< 分区类型
    uint8_t end_head;        ///< 结束头
    uint8_t end_sector;      ///< 结束扇区（低6位有效）
    uint8_t end_cylinder;    ///< 结束柱面
    uint32_t start_lba;      ///< 起始LBA地址
    uint32_t size;           ///< 分区大小（扇区数）
} PartitionEntry;

/**
 * @brief 解析MBR中的分区表并打印每个分区的信息
 * 
 * @param mbr_data 指向MBR数据的字节数组指针
 * 
 * 该函数将解析MBR中的分区表信息，并打印每个分区的状态、类型、起始和结束位置（CHS和LBA）以及大小等信息。
 */
void parse_partition_table(const uint8_t* mbr_data) {
    for (int i = 0; i < NUM_PARTITIONS; ++i) {
        const uint8_t* entry_offset = mbr_data + PARTITION_TABLE_START + i * PARTITION_ENTRY_SIZE;
        PartitionEntry entry;

        entry.status = entry_offset[0];
        entry.start_head = entry_offset[1];
        entry.start_sector = entry_offset[2] & 0x3F;  // 扇区号是低6位
        entry.start_cylinder = ((entry_offset[2] & 0xC0) << 2) | entry_offset[3];
        entry.partition_type = entry_offset[4];
        entry.end_head = entry_offset[5];
        entry.end_sector = entry_offset[6] & 0x3F;    // 扇区号是低6位
        entry.end_cylinder = ((entry_offset[6] & 0xC0) << 2) | entry_offset[7];
        entry.start_lba = *(uint32_t*)(entry_offset + 8);
        entry.size = *(uint32_t*)(entry_offset + 12);

        printf("Partition %d:\n", i + 1);
        printf("  Status: 0x%02X (%s)\n", entry.status, (entry.status == 0x80) ? "Active" : "Inactive");
        printf("  Type: 0x%02X\n", entry.partition_type);
        printf("  Start CHS: %d/%d/%d\n", entry.start_cylinder, entry.start_head, entry.start_sector);
        printf("  End CHS: %d/%d/%d\n", entry.end_cylinder, entry.end_head, entry.end_sector);
        printf("  Start LBA: %u\n", entry.start_lba);
        printf("  Size (sectors): %u\n", entry.size);
        printf("\n");
    }
}

/**
 * @brief 程序入口
 * 
 * 从指定设备文件读取MBR数据，并调用函数解析分区表。
 */
int main() {
    uint8_t mbr[MBR_SIZE] = {0};  ///< 缓冲区，用于存储从MBR读取的数据

    FILE *file = fopen("/dev/vda", "rb");  ///< 打开设备文件以读取MBR
    if (file) {
         fread(mbr, 1, MBR_SIZE, file);  ///< 读取MBR数据到缓冲区
         fclose(file);                   ///< 关闭文件
     }

    parse_partition_table(mbr);  ///< 解析MBR中的分区表

    return 0;  ///< 返回程序执行的状态码
}
